package com.ww.springboot.boot.algorithm.leetcode1;

import java.util.ArrayList;
import java.util.List;

/**
 * 描述：
 * 给你一个整数 n ，按字典序返回范围 [1, n] 内所有整数。
 * <p>
 * 你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。
 * <p>
 *  
 * <p>
 * 示例 1：
 * <p>
 * 输入：n = 13
 * 输出：[1,10,11,12,13,2,3,4,5,6,7,8,9]
 * 示例 2：
 * <p>
 * 输入：n = 2
 * 输出：[1,2]
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/lexicographical-numbers
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * @author 🧑 ‍wanwei
 * @since 2022-11-11 16:28
 */
public class CO字典序排数 {

    public static void main(String[] args) {

        List<Integer> list = lexicalOrder(8);

        System.out.println(list);
        System.out.println(list.size());
    }


    /**
     * 深度优先
     * 1.尝试补0 ;直到大于等于n
     * 2.+1直到大于等于n 或者尾数变为9 则向前回退一位再继续之前的+1操作 每次退位超过2位时都尝试补0操作
     *
     * @param n
     * @return
     */
    public static List<Integer> lexicalOrder(int n) {
        int i = 1;
        List<Integer> list = new ArrayList<>();

        while (true) {
            list.add(i);
            while (i * 10 <= n) {
                //补0
                i *= 10;
                list.add(i);
            }
            while (i % 10 < 9 && i + 1 <= n) {
                //累加1
                i += 1;
                list.add(i);
            }

            while (i > 9 && (i % 10 == 9 || i == n)) {
                //如果i 尾数是9 则继续往前退位
                i /= 10;
            }

            if (i == 9 || i + 1 > n) {
                break;
            }
            i += 1;
        }
        return list;
    }


}
